package com.hzhr.iot.login.aop;

import com.hzhr.iot.core.constant.HzhrAttrNames;
import com.hzhr.iot.core.constant.HzhrHeaderNames;
import com.hzhr.iot.core.constant.ServiceErrors;
import com.hzhr.iot.core.dto.ResponseExceptionDto;
import com.hzhr.iot.core.exception.ServiceException;
import com.hzhr.iot.core.model.ResponseModel;
import com.hzhr.iot.core.util.HzhrTypeUtil;
import com.hzhr.iot.log.sdk.model.log.LogModel;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;


@Aspect
@Component
@Order(2)
public class HttpAspect {
    @Autowired
    HttpServletRequest request;

    @Value("${spring.profiles.active}")
    String active;

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Pointcut("execution(* com.hzhr.iot.login.controller..*(..))")
    public void httpPointCut() {
    }

    @Before("httpPointCut()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
    }

    @AfterReturning(returning = "ret", pointcut = "httpPointCut()")
    public void doAfterReturning(Object ret) throws Throwable {
    }

    @Around("httpPointCut()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {
        String trasactionId = HzhrTypeUtil.object2string(request.getAttribute(HzhrHeaderNames.TRANSACTION_ID));
        try {
            Object result = joinPoint.proceed();
            try {
                ResponseEntity<ResponseModel> response = (ResponseEntity<ResponseModel>)result;
                ResponseModel responseModel = response.getBody();
                responseModel.setTransactionId(trasactionId);
                return response;
            } catch (Exception e) {
                return result;
            }
        } catch (ServiceException e) {
            logger.error("服务端异常", e);

            LogModel log = (LogModel)request.getAttribute(HzhrAttrNames.LOG);

            ResponseExceptionDto responseExceptionDto = new ResponseExceptionDto();
            ServiceErrors serviceErrors = e.getServiceErrors();
            HttpStatus httpStatus = serviceErrors.getHttpStatus();
            responseExceptionDto.setCode(serviceErrors.getCode());
            responseExceptionDto.setTransactionId(trasactionId);
            if (!active.endsWith("prod")) {
                responseExceptionDto.setDebug(log.getExceptionInfo());
                responseExceptionDto.setDes(serviceErrors.getMessage());
                responseExceptionDto.setType(serviceErrors.getServiceExceptionCategory().getDes());
                responseExceptionDto.setBusiness(serviceErrors.getBusiness());
            }
            return new ResponseEntity<>(responseExceptionDto, httpStatus);
        }  catch (Exception e) {
            logger.error("未知异常", e);

            LogModel log = (LogModel)request.getAttribute(HzhrAttrNames.LOG);
            log.appendExceptionInfo(e);

            ResponseExceptionDto responseExceptionDto = new ResponseExceptionDto();
            responseExceptionDto.setCode(0);
            responseExceptionDto.setTransactionId(trasactionId);
            if (!active.endsWith("prod")) {
                responseExceptionDto.setDebug(log.getExceptionInfo());
                responseExceptionDto.setDes("未知错误!");
            }
            return new ResponseEntity<>(responseExceptionDto, HttpStatus.INTERNAL_SERVER_ERROR);
        }
    }
}